package com.scalar.chiptrack.adaptor.ikanos.tsmc;

import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.AdaptorUtils;
import com.scalar.chiptrack.adaptor.FabSortLot;
import com.scalar.chiptrack.adaptor.ShippedLot;
import com.scalar.chiptrack.adaptor.gtc.GTCSortBinReport;
import com.scalar.chiptrack.adaptor.tsmc.TSMCLotStatus;
import com.scalar.chiptrack.adaptor.tsmc.TSMCShippingInfo;
import com.scalar.chiptrack.adaptor.dao.AdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorRunInfo;
import com.scalar.chiptrack.adaptor.dao.FabSortAdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.ShippedLotDAO;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.chiptrack.utils.StringUtils;
import com.scalar.ScalarException;

import java.util.HashMap;
import java.util.ArrayList;
import java.util.Iterator;
import java.io.File;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

/**
 * User: ChandraSekhar
 * Date: Feb 13, 2008
 * Time: 7:18:59 PM
 */
public class TSMCDataParser extends JobHandler implements AdaptorConstants
{
    private static Logger m_parserLogger    = null;
    private String m_dataOutputDir          = null;
    private HashMap<String, FabSortLot> m_fabWipDataMap         = new HashMap<String, FabSortLot>();
    private HashMap<String, ShippedLot> m_fabShipDataMap        = new HashMap<String, ShippedLot>();
    private HashMap<String, FabSortLot> m_sortWipDataMap        = new HashMap<String, FabSortLot>();
    private HashMap<String, ShippedLot> m_sortShipDataMap       = new HashMap<String, ShippedLot>();
    private HashMap<String, FabSortLot> m_sortBinDataMap        = new HashMap<String, FabSortLot>();

    int m_waferQtyIn            = 0;
    int m_totalPassQty          = 0;
    float m_totalYield          = 0.0f;
    public TSMCDataParser() throws ScalarException
    {
        try
        {    m_dataOutputDir = AdaptorUtils.getDataOutputDir( VENDOR_NAME_TSMC, WIP_TYPE_FAB );
            AdaptorUtils.makeAllAdaptorDirs( m_dataOutputDir );

            m_parserLogger = AdaptorUtils.getDataParserLogger( m_dataOutputDir, VENDOR_NAME_TSMC );
            FabSortAdaptorDAO.setLogger( m_parserLogger );
            ShippedLotDAO.setLogger( m_parserLogger );
            AdaptorUtils.setLogger( m_parserLogger );
        }
        catch ( ScalarException se )
        {
            log( "ERROR!! ERROR!! ERROR!! Exception while loading TSMC WIP output directory details from database, Exception: " + se );
            throw se;
        }
    }
    /**
     *
     * @param args
     * @throws Exception
     */
    public static void main( String args[] ) throws Exception
    {
        try
        {
            new TSMCDataParser().execute();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
     *
     */
    public void execute() throws Exception
    {
        //Print the header details
        AdaptorUtils.printHeader(VENDOR_NAME_TSMC, CONSTANT_PARSER);

        File doneDestDir = new File(  m_dataOutputDir + "/done" );

        File sourceDataoutDir = new File( m_dataOutputDir );

        File[] fileList = sourceDataoutDir.listFiles();
        if ( ( fileList == null ) || ( fileList.length <= 3 ) )
        {
            log( "No file found in directory: " + sourceDataoutDir );
            throw new ScalarException( "\n+-----------No file found in directory " + sourceDataoutDir );
        }

        ArrayList<TSMCLotStatus> tsmcWipList     = null;
        ArrayList<TSMCShippingInfo> tsmcShipList    = null;
        ArrayList<File> successFileList = new ArrayList<File>();
        boolean success           = false;

        try
        {
            for ( int i = 0; i < fileList.length; i++ )
            {
                if ( fileList[i].isDirectory() == true )
                {
                    continue;
                }
               
               if ( ( fileList[i].getName() != null ) && ( fileList[i].getName().trim().startsWith( TSMCAdaptor.ORDERVSLOT_FILE_NAME ) ) )
                {
                    try
                    {
                       tsmcWipList = parseWipInfo( fileList[i].getAbsolutePath() );
                        if ( tsmcWipList != null )
                        {
                            getTSMCWipList( tsmcWipList );
                        }
                        successFileList.add( fileList[i] );
                        success = true;
                    }
                    catch ( Exception e )
                    {
                        success = false;
                        log( "Exception while parsing and storing file: " + fileList[i].getAbsolutePath() + "\nException: " + e );
                        e.printStackTrace();
                        throw e;
                    }
                }
                if ( ( fileList[i].getName() != null ) && ( fileList[i].getName().trim().startsWith( TSMCAdaptor.SHIPPING_FILE_NAME ) ) )
                {
                    try
                    {
                        tsmcShipList = parseShippingInfo( fileList[i].getAbsolutePath() );
                        if ( tsmcShipList != null )
                        {
                            getTSMCShipList( tsmcShipList );
                        }

                        successFileList.add( fileList[i] );
                        success = true;
                    }
                    catch ( Exception e )
                    {
                        success = false;
                        log( "Exception while parsing and storing file: " + fileList[i].getAbsolutePath() + "\nException: " + e );
                        e.printStackTrace();
                        throw e;
                    }
                }
                if ((fileList[i].getName() != null) && (fileList[i].getName().trim().startsWith(TSMCAdaptor.BINING_FILE_NAME )))
                {
                    try
                    {
                        ArrayList<GTCSortBinReport> sortlotbinList = parseSortLotBinReport( fileList[i].getAbsolutePath() );

                        //To get the Sort Binning information
                        getSortBinDetails( sortlotbinList );

                        successFileList.add(fileList[i]);
                        success = true;
                    }
                    catch (Exception e)
                    {
                        success = false;
                        log("Exception while parsing and storing file: " + fileList[i].getAbsolutePath() + "\nException: " + e);
                        e.printStackTrace();
                        throw e;
                    }
                }
            }
        }
        catch ( Exception e )
        {
            success = false;
            log( "ERROR!! ERROR!! ERROR!! While parsing and storing File " + e );
            e.printStackTrace();
            throw e;
        }
        /*if ( tsmcWipList != null && tsmcWipList.size() > 0 )
        {
            TSMCDAO.saveTSMCWipDetails( null, tsmcWipList);
        }
        if ( tsmcShipList != null && tsmcShipList.size() > 0 )
        {
            TSMCDAO.saveTSMCShipDetails( null, tsmcShipList);
        }*/
        // to save the Fab lot tables
        try
        {
            if ( m_fabWipDataMap.isEmpty() == false )
            {
                log( "Updating Fab Lot Information" );
                FabSortAdaptorDAO.saveFabLot( null,  m_fabWipDataMap.values().iterator(), WIP_TYPE_FAB, VENDOR_NAME_TSMC );
            }
            else
            {
                System.out.println( "This is FAB Data Parser FAB Part Number List is empty" );
                FabSortAdaptorDAO.closeFabSortLot( null, WIP_TYPE_FAB, VENDOR_NAME_TSMC );
            }
            success = true;
        }
        catch ( Exception e )
        {
            success = false;
            log( "ERROR!! ERROR!! ERROR!! Could not update Fab Data information into database: " + e );
            e.printStackTrace();
            throw e;
        }
        try
        {
            // Save shipping info -
            if ( m_fabShipDataMap.isEmpty() == false )
            {
                log( "Updating shipment Information" );
                ShippedLotDAO.saveShippedLot( null, m_fabShipDataMap.values().iterator() );
            }
            success = true;
        }
        catch ( Exception e )
        {
            success = false;
            log( "ERROR!! ERROR!! ERROR!! Could not update TSMC Fab Shipping information into database: " + e );
            e.printStackTrace();
            throw e;
        }
        try
        {
            if ( m_sortBinDataMap.isEmpty() == false )
            {
                FabSortAdaptorDAO.saveSortBinData( null, m_sortBinDataMap.values().iterator() );
            }
            success = true;
            m_sortBinDataMap.clear();
        }
        catch(Exception e)
        {
            success = false;
            System.out.println(" Exception Occrred While Saving the Sort Binning Info " +e );
            throw e;
        }
        try
        {
            if ( m_sortWipDataMap.isEmpty() == false )
            {
                log( "Updating SORT Lot Information" );
                FabSortAdaptorDAO.saveSortLot( null, m_sortWipDataMap.values().iterator(), WIP_TYPE_SORT, VENDOR_NAME_TSMC );
            }
            else
            {
                System.out.println( "This is FAB Data Parser SORT Part Number List is empty" );
                FabSortAdaptorDAO.closeFabSortLot( null, WIP_TYPE_SORT, VENDOR_NAME_TSMC );
            }
        }
        catch ( Exception e )
        {
            success = false;
            log( "ERROR!! ERROR!! ERROR!! Could not update SORT Data information into database: " + e );
            e.printStackTrace();
            throw e;
        }

        try
        {
            // Save shipping info -
            if ( m_sortShipDataMap.isEmpty() == false )
            {
                log( "Updating shipment Information" );
                ShippedLotDAO.saveShippedLot( null, m_sortShipDataMap.values().iterator() );
            }
            success = true;
        }
        catch ( Exception e )
        {
            success = false;
            log( "ERROR!! ERROR!! ERROR!! Could not update TSMC Fab Shipping information into database: " + e );
            e.printStackTrace();
            throw e;
        }

        // To Close the Drop Out Lots
        AdaptorDAO.closeDropOutLots( VENDOR_NAME_TSMC );

        // TO SEND THE NEW LOTS, NEW TRANSIT LOTS, NO PO LOTS, DISCREPANCY LOTS NOTIFICATIONS TO THE USER
        AdaptorDAO.sendAllNotifications( VENDOR_NAME_TSMC, true, true, true );
              

        int adaptor_id = AdaptorRunInfo.getLastRunAdaptorId( TSMCAdaptor.ADAPTOR_NAME, CONSTANT_ADAPTOR);

        // Update Adaptor_Run_Info table
        try
        {
            if ( success == true )
            {
                AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, TSMCAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
                System.out.println( "SUCCESSFULLY UPDATED IN THE DATABASE" );
            }
        }
        catch ( ScalarException se )
        {
            success = false; //As filES DATA SAVED , UPDATEING AS SUCCESS
            AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, TSMCAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
            log( "WARNING!! WARNING!! WARNING!! Could not update Adaptor run information, Exception: " + se );
            throw se;
        }
        // Move the successful files to 'done' directory
       if ( success )
       {
           AdaptorUtils.moveFilesToDone( successFileList, doneDestDir );
       }
    }//end of execute method


    public void getTSMCWipList( ArrayList wipdataList ) throws Exception
    {
        TSMCLotStatus lotStatus = null;
        String partNumber       = null;
        String lotNumber        = null;
        FabSortLot fabSortLot   = null;

        try
        {
            Iterator iterator = wipdataList.iterator();
            while ( iterator.hasNext() )
            {
                lotStatus = ( TSMCLotStatus ) iterator.next();

                if ( lotStatus != null && "SHIPPED".equalsIgnoreCase( lotStatus.getCurrentStage() ) == false && "SCRAP".equalsIgnoreCase( lotStatus.getCurrentStage() ) == false )
                {
                    partNumber = lotStatus.getCustomerProduct();
                    lotNumber  = lotStatus.getTsmcLotID();

                    if ( lotStatus.getDieQty() != null )
                    {
                        fabSortLot = m_sortWipDataMap.get( partNumber + lotNumber );
                        if ( fabSortLot == null )
                        {
                            fabSortLot = new FabSortLot(VENDOR_NAME_TSMC, WIP_TYPE_SORT );
                            m_sortWipDataMap.put( partNumber + lotNumber , fabSortLot );
                        }
                    }
                    else
                    {

                        fabSortLot = m_fabWipDataMap.get( partNumber + lotNumber );
                        if ( fabSortLot == null )
                        {
                            fabSortLot = new FabSortLot(VENDOR_NAME_TSMC, WIP_TYPE_FAB );
                            m_fabWipDataMap.put( partNumber + lotNumber , fabSortLot );
                        }
                    }
                    int quantity = 0;
                    if ( fabSortLot.getQtyIn() != null )
                    {
                        try
                        {
                            quantity = Integer.parseInt( fabSortLot.getQtyIn() );
                        }
                        catch ( NumberFormatException ignore )
                        {
                        }
                        try
                        {
                            quantity += Integer.parseInt( lotStatus.getWaferQty() );
                        }
                        catch ( NumberFormatException ignore )
                        {
                        }
                    }
                    else
                    {
                        try
                        {
                            quantity = Integer.parseInt( lotStatus.getWaferQty() );
                        }
                        catch ( NumberFormatException ignore )
                        {
                        }
                    }

                    if ( quantity > 0 )
                    {
                        fabSortLot.setLotId( lotNumber );
                        fabSortLot.setCustProduct( partNumber );
                        fabSortLot.setDateIn( lotStatus.getWaferStartDate() );
                        fabSortLot.setQtyIn( quantity +"");
                        fabSortLot.setStage( lotStatus.getCurrentStage() );
                        fabSortLot.setWaferID( lotStatus.getWaferID() );// not IN Sheet
                        fabSortLot.setFabLotNumber( lotNumber );
                        fabSortLot.setFabId ( lotStatus.getWaferFab() );
                        fabSortLot.setWsQty ( lotStatus.getWaferStartQty() );
                        fabSortLot.setLotCategory( LOT_CATEGORY_TYPE_PROD );
                        fabSortLot.setPoNumber( lotStatus.getCustomerPo() );
                        fabSortLot.setShip_fcst_date( lotStatus.getCommitDate() );
                        fabSortLot.setForcastedDateOut(  lotStatus.getProjectedOutDate() );
                        fabSortLot.setOutLookDate( lotStatus.getCommitDate() );
                        fabSortLot.setStagePosition( lotStatus.getStageSeq() );
                        fabSortLot.setFabLotNumber( lotNumber );
                        if ( lotStatus.getHoldFlag() != null )
                        {
                            fabSortLot.setLotStatus( LOT_STATUS_HOLD );
                        }
                        else
                        {
                            fabSortLot.setLotStatus( LOT_STATUS_RUNNING );
                        }
                    }
                }
            }
        }
        catch(Exception e)
        {
            System.out.println(" Error while parsing the Lot vs Order wip status " + e);
            e.printStackTrace();
        }
    }

    /**  For ORDER Vs Lot Status Sheet
    * Reads, parses the file and saves into database
    */
    private  ArrayList<TSMCLotStatus> parseWipInfo( String fileName ) throws Exception
    {
        if ( fileName == null ) throw new ScalarException( "Filename argument is null" );

        ArrayList<TSMCLotStatus> statusList    = new ArrayList<TSMCLotStatus>();
        String line             = null;

        try
        {
            File wipInfoFile = new File( fileName );
            if ( wipInfoFile.exists() == false )
            {
                throw new ScalarException( fileName + " doesnt exist" );
            }

            log( "\nFound " + fileName );
            log( "Parsing the file for WIP Status Report..." );
            System.out.println( "\nFound " + fileName );
            System.out.println( "Parsing the file for WIP Status Report..." );

            BufferedReader reader = new BufferedReader( new FileReader( fileName ) );

            reader.readLine();  // skip 1st line
            reader.readLine();  // skip 2nd line

            while ( ( line = reader.readLine() ) != null )
            {
                TSMCLotStatus wipInfo = new TSMCLotStatus();

                line = line.replaceAll( "\"", "" );

                String[] token = line.split(",");

                for (int x = 0; x < token.length; x++)
                {
                    if (token[x] != null && token[x].trim().length() > 0)
                    {
                        switch (x)
                        {
                            case 0:
                                wipInfo.setCustomerPo(token[x].trim());
                                break;
                            case 1:
                                wipInfo.setTsmcProduct( token[x].trim() );
                                break;
                            case 2:
                                wipInfo.setCustomerProduct(token[x].trim());
                                break;
                            case 3:
                                wipInfo.setTsmcLotID(token[x].trim());
                                break;
                            case 4:
                                wipInfo.setWaferStartQty(token[x].trim());
                                break;
                            case 5:
                                wipInfo.setWaferStartDate(token[x].trim());
                                break;
                            case 6:
                                wipInfo.setStageSeq(token[x].trim());
                                break;
                            case 7:
                                wipInfo.setCurrentStage(token[x].trim());
                                break;
                            //case 8:  Current Size
                            case 9:
                                wipInfo.setWaferQty( token[x].trim() );  //Qty netted to Order
                                break;
                            case 10:
                                wipInfo.setProjectedOutDate( token[x].trim().equalsIgnoreCase("Cust Hold") ? null : token[x].trim() );
                                break;
                            //case 11: Shipped Quantity
                            //case 12: Ship Date
                            //case 13: Gross Die/wafer
                            case 14:
                                wipInfo.setDieQty(token[x].trim());
                                break;
                            //case 15: Yield
                            //case 16: Equivalent shipped wafer Qty
                            case 17:
                                wipInfo.setCommitDate( token[x].trim().equalsIgnoreCase("Order Hold") ? null : token[x].trim());
                                break;
                            case 18:
                                wipInfo.setCustomerLotID( token[x].trim() );
                                break;
                            case 19:
                                wipInfo.setCurrentMfgPart( token[x].trim() );
                                break;
                            //case 20: Current Stage In Time
                            //case 21: Lot Attribute
                            //case 22: Backup Fab
                            case 23:
                                wipInfo.setHoldFlag( token[x].trim() );
                                break;
                            //case 24: Comp. Name
                            case 25:
                                wipInfo.setWaferFab( token[x].trim() );
                                break;
                        }
                    }
                }
                if ( wipInfo.getCustomerProduct() != null && wipInfo.getCustomerProduct().length() > 0 &&
                     wipInfo.getTsmcLotID() != null && wipInfo.getTsmcLotID().length() > 0
                        && "SHIPPED".equalsIgnoreCase( wipInfo.getCurrentStage() ) == false && "SCRAP".equalsIgnoreCase( wipInfo.getCurrentStage() ) == false)
                {
                    statusList.add( wipInfo );
                }
            }

            try
            {
                if ( reader != null )
                {
                   reader.close();
                }
            }
            catch(IOException ignore)
            {

            }

        }
        catch (Exception e)
        {
            System.out.println("Exception while parsing Wip Info: " + e);
            System.out.println("Line: " + line);
            throw new ScalarException("Exception while parsing Wip Info: " + e + "\nLine: " + line, e);
        }

        return statusList;
    }

    /**
     * Reads, parses the file and saves into database
     */
    private  ArrayList<TSMCShippingInfo> parseShippingInfo( String fileName ) throws Exception
    {

        if ( fileName == null ) throw new ScalarException( "Filename argument is null" );

        ArrayList<TSMCShippingInfo> shippingInfoList = new ArrayList<TSMCShippingInfo>();
        BufferedReader fileReader = null;

        try
        {
            File shippingInfoFile = new File( fileName );
            if ( shippingInfoFile.exists() == false )
            {
                throw new ScalarException( fileName + " doesnt exist" );
            }

            System.out.println( "Found " + fileName );
            System.out.println( "Parsing the file for Product Information..." );

            fileReader = new BufferedReader( new FileReader( shippingInfoFile ) );

            String line = null;
            TSMCShippingInfo shippingInfo = null;
            ArrayList<String> errors = new ArrayList<String>();

            fileReader.readLine();  // skip 1st line
            fileReader.readLine();  // skip 2nd line

            while ( ( line = fileReader.readLine() ) != null )
            {

                try
                {
                    shippingInfo = parseShippingInfoLine( line );
                }
                catch ( ScalarException pe )
                {
                    shippingInfo = null;
                    errors.add( pe.getMessage() );
                }

                if ( shippingInfo != null )
                {
                    shippingInfoList.add( shippingInfo );
                }
            }

            fileReader.close();
            fileReader = null;

            System.out.println( "Done parsing.." );

            if ( errors.isEmpty() == false )
            {   // Parser Errors, Send mail to ChipTrac System Administrator
                System.out.println( "\nFound errors... notifying system administrator..." );
                System.out.println( "done\n" );
            }
        }
        finally
        {
            if ( fileReader != null )
            {
                try
                {
                    fileReader.close();
                }
                catch ( IOException ignore )
                {
                }
            }
        }

        return shippingInfoList;
    }

    /**
     * Parses each line into TSMCShippingInfo object
     *
     * @param line to parse
     * @return TSMCShippingInfo parsed data object
     *
     * @throws com.scalar.chiptrack.adaptor.ParserException if there is any problem parsing the line
     */
    private TSMCShippingInfo parseShippingInfoLine( String line ) throws ScalarException
    {

        TSMCShippingInfo shippingInfo = null;

        if ( ( line == null ) || ( line.startsWith( "---" ) ) || ( line.trim().length() < 70 /*min length*/ ) )
        {
            return shippingInfo;
        }

        String[] lineToken = line.split("\"");

        if (lineToken != null && lineToken.length > 1)
        {
            lineToken[1] = lineToken[1].replaceAll(",", "");
        }

        line = "";
        for (int i = 0; i < lineToken.length; i++)
        {
            line = line + lineToken[i];
        }

        try
        {
            String[] token = line.split(",");
            shippingInfo = new TSMCShippingInfo();

            for (int x = 0; x < token.length; x++)
            {
                if (token[x] != null && token[x].trim().length() > 0)
                {
                    switch (x)
                    {
                        case 0:
                            shippingInfo.setInvoiceDate(token[x].trim());
                            break;
                        case 1:
                            shippingInfo.setInvoiceNo(token[x].trim());
                            break;
                        case 2:
                            shippingInfo.setCustomerPO(token[x].trim());
                            break;
                        case 3:
                            shippingInfo.setCustomerProduct(token[x].trim());
                            break;
                        case 4:
                            shippingInfo.setTsmcProduct(token[x].trim());
                            break;
                        case 5:
                            shippingInfo.setUm(token[x].trim());
                            break;
                        case 6:
                            shippingInfo.setCustomerLotID(token[x].trim());
                            break;
                        case 7:
                            shippingInfo.setTsmcLotID(token[x].trim());
                            break;
                        case 8:
                            shippingInfo.setShipQty(token[x].trim());
                            break;
                        case 9:
                            shippingInfo.setComment(token[x].trim());
                            break;
                        case 10:
                            shippingInfo.setWaferQty(token[x].trim());
                            break;
                        case 11:
                            shippingInfo.setDieQty(token[x].trim());
                            break;
                        case 12:
                            shippingInfo.setShipTo(token[x].trim());
                            break;
                        //case 13
                        case 14:
                            shippingInfo.setWaferID(token[x].trim());
                            break;
                    }
                }
            }

        }
        catch (Exception e)
        {
            System.out.println( "Exception while parsing Shipping Info: " + e );
            System.out.println( "Line: " + line );
            throw new ScalarException("Exception while parsing Shipping Info: " + e + "\nLine: " + line, e );
        }

        return shippingInfo;
    }
    /**
    *
    * @param shipdataList
    */
   private void getTSMCShipList( ArrayList shipdataList )
   {
       TSMCShippingInfo tsmcShipReport = null;
       ShippedLot shippedLot = null;
       FabSortLot   sortBinLot = null;
       String partNumber = null;
       String lotNumber  = null;
       String shipDate   = null;

       Iterator iterator = shipdataList.iterator();

       while ( iterator.hasNext() )
       {
           tsmcShipReport = ( TSMCShippingInfo ) iterator.next();

           partNumber   = tsmcShipReport.getCustomerProduct();
           lotNumber    = tsmcShipReport.getTsmcLotID();
           shipDate     = tsmcShipReport.getInvoiceDate();

            if ( tsmcShipReport != null && tsmcShipReport.getTsmcLotID() != null && tsmcShipReport.getTsmcLotID().length() > 0 && tsmcShipReport.getWaferQty() != null
                && tsmcShipReport.getWaferQty().trim().length() > 0  )
            {

                if (tsmcShipReport.getDieQty() != null )
                {
                    shippedLot = m_sortShipDataMap.get( lotNumber + partNumber + shipDate + tsmcShipReport.getShipTo() + tsmcShipReport.getCustomerPO() );

                    if ( shippedLot == null )
                    {
                        shippedLot = new ShippedLot(VENDOR_NAME_TSMC, LOCATION_TYPE_SORT );
                        m_sortShipDataMap.put( lotNumber + partNumber + shipDate + tsmcShipReport.getShipTo() + tsmcShipReport.getCustomerPO(), shippedLot );
                    }
                }
                else
                {
                     shippedLot = m_fabShipDataMap.get( lotNumber + partNumber + shipDate + tsmcShipReport.getShipTo() + tsmcShipReport.getCustomerPO() );
                     if ( shippedLot == null )
                     {
                          shippedLot = new ShippedLot(VENDOR_NAME_TSMC, LOCATION_TYPE_FAB );
                          m_fabShipDataMap.put( lotNumber + partNumber + shipDate + tsmcShipReport.getShipTo() + tsmcShipReport.getCustomerPO(), shippedLot );
                     }
                }

                int quantity = 0;
                if ( shippedLot.getShipQty() != null )
                {
                   try
                   {
                       quantity = Integer.parseInt( shippedLot.getShipQty() );
                   }
                   catch ( NumberFormatException ignore )
                   {
                   }
                   try
                   {
                       quantity += Integer.parseInt( tsmcShipReport.getShipQty() );
                   }
                   catch ( NumberFormatException ignore )
                   {
                   }
                }
                else
                {
                   try
                   {
                       quantity = Integer.parseInt( tsmcShipReport.getShipQty() );
                   }
                   catch ( NumberFormatException ignore )
                   {
                   }
                }

                if ( quantity > 0 )
                {
                    if ( LOCATION_TYPE_SORT.equalsIgnoreCase(shippedLot.getCurrentLocation() ) )
                    {
                        /*String waferArray[] = null;
                        if ( tsmcShipReport.getWaferID() != null )
                        {
                            waferArray = tsmcShipReport.getWaferID().split(";");
                        }*/
                        shippedLot.setShipDieQty( quantity +""); // DIE QTY 
                        shippedLot.setShipQty( tsmcShipReport.getWaferQty() );
                        /*int remainQty = quantity%Integer.parseInt(tsmcShipReport.getWaferQty() ); //MODULUS OF QTY

                        for (int i=0; i<waferArray.length; i++ )
                        {
                            String waferId = waferArray[i];

                             if (waferId != null )
                             {
                                sortBinLot = ( FabSortLot ) m_sortBinDataMap.get( partNumber + lotNumber + waferId );

                                if ( sortBinLot == null )
                                {
                                    sortBinLot = new FabSortLot( VENDOR_NAME_TSMC, LOCATION_TYPE_SORT );
                                    m_sortBinDataMap.put( partNumber + lotNumber + waferId , sortBinLot );
                                }

                                sortBinLot.setCustProduct( partNumber );
                                sortBinLot.setLotId( lotNumber );
                                sortBinLot.setWaferID( waferId );
                                 // WAFER QTY IN Always Same(total wafers) ,But For Each every Wafer update the Wafer Qty, the the WaferQty
                                sortBinLot.setQtyIn(  tsmcShipReport.getWaferQty() );
                                sortBinLot.setDateIn( shipDate );
                                sortBinLot.setTotalgoodDieQtyIn( quantity );
                                sortBinLot.setTotalprobeQtyIn( quantity );

                                if ( i < remainQty )
                                {
                                    sortBinLot.setGoodDieQtyIn( (quantity/Integer.parseInt(tsmcShipReport.getWaferQty() ) ) + 1 );
                                }
                                else
                                {
                                    sortBinLot.setGoodDieQtyIn( quantity/Integer.parseInt(tsmcShipReport.getWaferQty() ) );
                                }
                                sortBinLot.setRejectedQtyIn(0 );
                                sortBinLot.setTotalYield( 0 ); // if sets as 0, in the PROC Yield Calculating (INQTY *100.00/OUTQTY)
                                sortBinLot.setBinNumber( "Bin1");
                                sortBinLot.setShipYield( 100+""); 
                                sortBinLot.setShipInfoLot( true ); 
                             }
                        }*/
                    }
                    else
                    {
                         shippedLot.setShipQty( quantity +"" );
                    }
                    shippedLot.setLotNumber( lotNumber );
                    shippedLot.setPartNumber( partNumber );
                    shippedLot.setShipDate( shipDate );
                    shippedLot.setInvoiceNumber( tsmcShipReport.getInvoiceNo() );
                    shippedLot.setCustomerPO( tsmcShipReport.getCustomerPO() );
                    shippedLot.setNextLocation ( tsmcShipReport.getShipTo() );
                    shippedLot.setWaferID( tsmcShipReport.getWaferID() );
                    shippedLot.setFabLotNumber( lotNumber );
                }
           }

       }
   }


    private ArrayList<GTCSortBinReport> parseSortLotBinReport( String fileName ) throws Exception
    {
        ArrayList<GTCSortBinReport> lotbinList = new ArrayList<GTCSortBinReport>();
        GTCSortBinReport sortBinReport = null;
        if ( fileName == null ) throw new ScalarException( "Filename argument is null" );

        // Phase-I variables
        File lotbinFile = new File( fileName );
        if ( lotbinFile.exists() == false )
        {
            throw new ScalarException( fileName + " doesnt exist" );
        }

        //System.out.println("fileName = " + fileName);

        System.out.println( "Found " + fileName );
        System.out.println( "\tParsing the file for Binning Information..." );

        String LOTNO    = "LOT NO:";
        String TESTER = "TESTER:";
        String PART_NO = "P/N:";
        String DATE_IN = "TEST DATE:";

        String deviceName = null;
        String lotNo = null;
        String dateIn = null;
        String testerName = null;
        String line = null;

        BufferedReader bReader = null;
        try
        {
            bReader = new BufferedReader( new FileReader( lotbinFile ) );

            while ( ( line = bReader.readLine() ) != null )
            {
                line = line.trim();
                //System.out.println("line = " + line);
                if ( line.indexOf("----------") != -1 || line.indexOf("Not Found") != -1 )
                {
                    break;
                }

                if ( line.indexOf( LOTNO ) != -1 )
                {
                    lotNo = line.substring( LOTNO.length(), line.indexOf(TESTER) ).trim();
                    //System.out.println("lotNo = " + lotNo);
                }
                if ( line.indexOf( TESTER ) != -1 )
                {
                    testerName = line.substring( line.indexOf(TESTER) + TESTER.length() ).trim();
                    //System.out.println("testerName = " + testerName);
                }
                if ( line.indexOf( PART_NO ) != -1 )
                {
                    deviceName = line.substring( PART_NO.length(), line.indexOf(DATE_IN) ).trim();
                   // System.out.println("deviceName = " + deviceName);
                }
                if ( line.indexOf( DATE_IN ) != -1 )
                {
                    dateIn = line.substring( line.indexOf(DATE_IN) + DATE_IN.length() ).trim();
                    dateIn = StringUtils.formatDate( dateIn, "dd-MMM-yyyy", "MM/dd/yyyy");
                    //System.out.println("dateIn = " + dateIn);
                }

            }
            bReader.close();
            bReader = null;
            line = null;
                      

            bReader = new BufferedReader( new FileReader( lotbinFile ) );
            while ( ( line = bReader.readLine() ) != null  )
            {
                line = line.trim();
                if ( line.indexOf("Not Found") != -1 )
                {
                    System.out.println("***********!!ERROR !!ERROR  file down loading failed *************");
                     break;
                }
                if ( line.indexOf( "PCS" ) != -1 )
                {                       
                    m_waferQtyIn = Integer.parseInt( line.substring( 3, line.indexOf( "PCS" ) ).trim() );
                    m_totalPassQty = Integer.parseInt( line.substring( line.indexOf( "PCS" ) + 3 , 40 ).trim() );
                    m_totalYield = Float.parseFloat(line.substring(65, 72).trim());
                    //System.out.println("m_waferQtyIn = " + m_waferQtyIn);
                    //System.out.println("m_totalPassQty = " + m_totalPassQty);
                    //System.out.println("m_totalYield = " + m_totalYield);

                    break;
                }
            }
            bReader.close();
            bReader = null;
            line = null;


            bReader = new BufferedReader( new FileReader( lotbinFile ) );
             //Reading the To Two Lines
            bReader.readLine();
            bReader.readLine();
            bReader.readLine();
            bReader.readLine();
            bReader.readLine();
            bReader.readLine();
            bReader.readLine();            
            while ( ( line = bReader.readLine() ) != null )
            {
                line = line.trim();
                //System.out.println("START line = " + line);

                if ( line.indexOf("PCS") != -1 || line.indexOf("Not Found") != -1)
                {
                    break;
                }
                if ( line.length() > 0 && lotNo != null && deviceName != null && ( !line.startsWith( "+------" ) ) && ( !line.startsWith( "|  WAFNO" ) ) && ( !line.startsWith( "1. LOT" ) ) )
                {
                    //System.out.println("line = " + line );

                    sortBinReport = new GTCSortBinReport();
                    String waferNo = line.substring( 3, 18 ).trim();
                    int waferId = Integer.parseInt( waferNo.substring(waferNo.indexOf(".") + 1, waferNo.indexOf(".") + 3 )  );

                    //System.out.println("waferId = " + waferId);
                    //System.out.println("line.substring(20, 40).trim() = " + line.substring(20, 40).trim());
                    //System.out.println("ine.substring(68, 78).trim() = " + line.substring(65, 72).trim());
                    int bin1QtyIn = Integer.parseInt(line.substring(20, 40).trim()); //TOTAL PASS IS TAKING AS BIN1 QTY

                    //System.out.println("bin1QtyIn = " + bin1QtyIn);


                    float waferYield = Float.parseFloat(line.substring(65, 72).trim());
                    //System.out.println("waferYield = " + waferYield);



                    if( lotNo != null && deviceName != null && waferId > 0 && waferId < 26 )
                    {
                        sortBinReport.setWaferId( waferId +"" );
                        sortBinReport.setGoodBinQty( bin1QtyIn );
                        sortBinReport.setDeviceName( deviceName );
                        sortBinReport.setDateIn( dateIn );
                        sortBinReport.setLotNumber( lotNo );
                        sortBinReport.setTester( testerName );
                        sortBinReport.setWaferYield( waferYield );

                        lotbinList.add(sortBinReport);
                    }
                }

            } //END OF WHILE
        }
        catch ( Exception e )
        {
            System.out.println( "Exception while parsing TSMC Sort Bin information \n" + e + "\n" );
            throw e;
        }
        finally
        {
            if ( bReader != null )
            {
                try
                {
                    bReader.close();
                }
                catch ( IOException ignore )
                {
                }
            }
        }
        return lotbinList;
    } // end of prase sortLot bin report method

    private void getSortBinDetails( ArrayList sortBinList )  throws Exception
    {
        if ( sortBinList == null || sortBinList.size() == 0 )
        {
           log( "No Sort Bin Lots when the List is Empty");
           return;
        }
        GTCSortBinReport sortbinReport  = null;
        String partNumber                = null;
        String lotNumber                 = null;
        String waferId                   = null;
        FabSortLot sortBinLot            = null;

        try
        {
            Iterator iterator = sortBinList.iterator();

            while ( iterator.hasNext() )
            {
                sortbinReport = (GTCSortBinReport )iterator.next() ;

                lotNumber  = sortbinReport.getLotNumber();
                waferId    = sortbinReport.getWaferId();
                partNumber = sortbinReport.getDeviceName();

                if ( partNumber != null && lotNumber != null && waferId != null )
                {
                   sortBinLot = ( FabSortLot ) m_sortBinDataMap.get( partNumber + lotNumber + waferId);

                    if ( sortBinLot == null )
                    {
                        sortBinLot = new FabSortLot( VENDOR_NAME_TSMC, LOCATION_TYPE_SORT );
                        m_sortBinDataMap.put( partNumber + lotNumber + waferId  , sortBinLot );
                    }

                    sortBinLot.setCustProduct( partNumber );
                    sortBinLot.setLotId( lotNumber );
                    sortBinLot.setWaferID( waferId );
                     // WAFER QTY IN Always Same(total wafers) ,But For Each every Wafer update the Wafer Qty, the the WaferQty
                    sortBinLot.setQtyIn( m_waferQtyIn +"" );
                    sortBinLot.setDateIn( sortbinReport.getDateIn() );
                    sortBinLot.setTotalgoodDieQtyIn( m_totalPassQty );

                    sortBinLot.setTesterNo( sortbinReport.getTester());
                    //sortBinLot.setTestProgram( sortbinReport.getTestPgm() );
                    sortBinLot.setGoodDieQtyIn(sortbinReport.getGoodBinQty());
                    sortBinLot.setRejectedQtyIn(sortbinReport.getRejectedQty() );
                    sortBinLot.setShipYield(sortbinReport.getWaferYield()+"");
                    sortBinLot.setTotalYield( m_totalYield ); // if sets as 0, in the PROC Yield Calculating (INQTY *100.00/OUTQTY)
                    sortBinLot.setBinNumber( "Bin1" );
               }
            }
        }
        catch(Exception e )
        {
            throw new ScalarException("Exception occured while parsing the Sort Bin Inforamtion" +e );
        }
    }
    /**
     *
     * @param message
     */
    private static void log( String message )
    {

        if ( message == null ) return;

        if ( m_parserLogger != null )
        {
            synchronized ( m_parserLogger )
            {
                m_parserLogger.logDebug( message + LINE_SEPARATOR );
            }
        }
        else
        {
            System.out.println( message );
        }
    }

}